package com.mango.leet.code.week2.game76;

/**
 * 6062. 设计一个 ATM 机器
 * @Author: mango
 * @Date: 2022/4/16 10:55 下午
 */

import java.lang.reflect.Array;
import java.util.Arrays;

/**
 * 一个 ATM 机器，存有 5 种面值的钞票：20 ，50 ，100 ，200 和 500 美元。初始时，ATM 机是空的。用户可以用它存或者取任意数目的钱。
 *
 * 取款时，机器会优先取 较大 数额的钱。
 *
 * 比方说，你想取 $300 ，并且机器里有 2 张 $50 的钞票，1 张 $100 的钞票和1 张 $200 的钞票，那么机器会取出 $100 和 $200 的钞票。
 * 但是，如果你想取 $600 ，机器里有 3 张 $200 的钞票和1 张 $500 的钞票，那么取款请求会被拒绝，因为机器会先取出 $500 的钞票，然后无法取出剩余的 $100 。注意，因为有 $500 钞票的存在，机器 不能 取 $200 的钞票。
 * 请你实现 ATM 类：
 *
 * ATM() 初始化 ATM 对象。
 * void deposit(int[] banknotesCount) 分别存入 $20 ，$50，$100，$200 和 $500 钞票的数目。
 * int[] withdraw(int amount) 返回一个长度为 5 的数组，分别表示 $20 ，$50，$100 ，$200 和 $500 钞票的数目，并且更新 ATM 机里取款后钞票的剩余数量。如果无法取出指定数额的钱，请返回 [-1] （这种情况下 不 取出任何钞票）。
 *
 *
 * 示例 1：
 *
 * 输入：
 * ["ATM", "deposit", "withdraw", "deposit", "withdraw", "withdraw"]
 * [[], [[0,0,1,2,1]], [600], [[0,1,0,1,1]], [600], [550]]
 * 输出：
 * [null, null, [0,0,1,0,1], null, [-1], [0,1,0,0,1]]
 *
 * 解释：
 * ATM atm = new ATM();
 * atm.deposit([0,0,1,2,1]); // 存入 1 张 $100 ，2 张 $200 和 1 张 $500 的钞票。
 * atm.withdraw(600);        // 返回 [0,0,1,0,1] 。机器返回 1 张 $100 和 1 张 $500 的钞票。机器里剩余钞票的数量为 [0,0,0,2,0] 。
 * atm.deposit([0,1,0,1,1]); // 存入 1 张 $50 ，1 张 $200 和 1 张 $500 的钞票。
 *                           // 机器中剩余钞票数量为 [0,1,0,3,1] 。
 * atm.withdraw(600);        // 返回 [-1] 。机器会尝试取出 $500 的钞票，然后无法得到剩余的 $100 ，所以取款请求会被拒绝。
 *                           // 由于请求被拒绝，机器中钞票的数量不会发生改变。
 * atm.withdraw(550);        // 返回 [0,1,0,0,1] ，机器会返回 1 张 $50 的钞票和 1 张 $500 的钞票。
 *
 *
 * 提示：
 *
 * banknotesCount.length == 5
 * 0 <= banknotesCount[i] <= 109
 * 1 <= amount <= 109
 * 总共 最多有 5000 次 withdraw 和 deposit 的调用。
 * 函数 withdraw 和 deposit 至少各有 一次 调用。
 */
public class LC6062 {
    /**
     * ["ATM","deposit","deposit","withdraw","withdraw","withdraw","withdraw","deposit","deposit","deposit","deposit","withdraw","withdraw","withdraw","withdraw","deposit","withdraw","deposit","withdraw","deposit","withdraw","withdraw","withdraw","withdraw","withdraw","withdraw","deposit","withdraw","withdraw","deposit","withdraw","withdraw","deposit","withdraw","withdraw","deposit","withdraw","deposit","deposit","withdraw","deposit","withdraw","withdraw","withdraw","withdraw","deposit","deposit","withdraw","deposit","deposit","deposit","deposit","withdraw","withdraw","withdraw","withdraw","withdraw","withdraw","withdraw","deposit","withdraw","deposit","deposit","deposit","withdraw","deposit","deposit","deposit","deposit","withdraw","withdraw","withdraw","deposit","withdraw","deposit","withdraw","deposit","withdraw","deposit","deposit","withdraw","deposit","deposit","deposit","deposit","deposit","deposit","withdraw","withdraw","deposit","withdraw","withdraw","deposit","deposit","deposit","deposit","deposit","deposit","withdraw","withdraw","deposit","withdraw","withdraw","deposit","deposit","deposit","withdraw","deposit","withdraw","deposit","deposit","withdraw","withdraw","withdraw","deposit","withdraw","deposit","deposit","deposit"]
     * [[],[[250796,638723,691758,845522,938973]],[[215317,848628,182949,784609,30472]],[701035245],[109992310],[755819795],[722349970],[[678816,841145,503892,325349,204606]],[[604328,586349,680353,733891,136713]],[[500950,53467,775875,469508,668335]],[[178876,500427,867418,738121,80412]],[824714410],[374969115],[351532175],[732076765],[[208564,707512,566329,300547,313109]],[774911195],[[742897,902293,512670,863273,105945]],[449705540],[[94829,872976,822744,630565,726268]],[981495000],[426983925],[591589125],[90436530],[300789750],[544232655],[[333998,671859,821084,678512,239841]],[816423815],[393272210],[[146335,604905,570672,384321,645355]],[184328925],[189043175],[[403571,361640,202265,108809,340899]],[630857120],[521903750],[[309733,543710,227714,682033,689707]],[409081030],[[140651,880799,664632,684067,189015]],[[653204,683646,273200,738271,768502]],[760807085],[[585693,749948,134852,936077,496241]],[598212970],[609144120],[173711145],[871970745],[[905672,917631,538045,213759,467121]],[[84394,842857,110657,83685,396409]],[283842105],[[547660,711399,37793,248979,171209]],[[721908,683510,507961,315580,915329]],[[724268,208639,86180,559536,369337]],[[18276,789197,268868,573790,51430]],[666573505],[402867945],[141646455],[989327245],[63547525],[793492260],[469750915],[[514958,777169,647876,692862,13212]],[134587615],[[698672,953618,770724,795084,787545]],[[381744,405569,839476,243652,173030]],[[371633,758052,510149,114478,847007]],[210704305],[[519428,519225,244531,859848,501054]],[[447308,71049,586248,739061,22236]],[[480462,388981,61696,465612,585484]],[[337913,996104,569476,144324,941825]],[875707660],[57569050],[313791115],[[495361,267828,569079,266649,318023]],[910215005],[[11564,454722,326554,617698,951649]],[737599780],[[459779,367480,721883,267540,616449]],[416183255],[[919244,501903,797594,255088,277900]],[[544488,760,373644,587808,462016]],[542186870],[[141787,245536,713162,249389,360758]],[[448335,140890,944469,820805,953212]],[[83472,483020,89382,734004,496270]],[[355454,592701,579669,600758,935825]],[[509278,123040,366474,967560,94569]],[[814617,106257,843008,148633,281962]],[92776780],[710233240],[[540287,779680,232597,843398,982588]],[943887435],[83641580],[[641807,238897,514709,878576,185671]],[[788165,163263,468077,187322,741170]],[[403619,495280,682590,976711,662733]],[[790416,971353,997540,833823,438455]],[[519889,768434,1186,576547,159969]],[[87541,987828,423814,667020,113391]],[739876825],[380847695],[[127434,690184,220342,251031,510668]],[736450270],[660460695],[[674760,193528,502970,437004,476214]],[[624107,419876,767550,454735,284487]],[[362461,226745,880847,364186,203497]],[102135095],[[187479,420361,4452,558218,944230]],[121284120],[[109227,412189,999147,755248,350021]],[[698704,927765,231972,325370,183792]],[380738930],[496198165],[119768090],[[907559,446837,965002,40373,684480]],[26609515],[[482552,665813,947214,295057,531240]],[[996330,771481,324291,338518,643748]],[[765310,513263,973288,667581,27556]]]
     * @param args
     */
    public static void main(String[] args) {
        ATM atm = new ATM();
        atm.deposit(new int[]{250796,638723,691758,845522,938973});
        atm.deposit(new int[]{215317,848628,182949,784609,30472});
        //System.out.println(Arrays.toString(atm.withdraw(701035245)));
        //System.out.println(Arrays.toString(atm.withdraw(109992310)));
        //System.out.println(Arrays.toString(atm.withdraw(755819795)));
        System.out.println(Arrays.toString(atm.withdraw(722349970)));

    }
    static class ATM {
        private long[] money;
        private long[] face;
        public ATM() {
            // 20,40,100,200,500
            money = new long[]{0,0,0,0,0};
            face = new long[]{20,50,100,200,500};
        }

        public void deposit(int[] banknotesCount) {
            for(int i=0;i<banknotesCount.length;i++){
                this.money[i] += banknotesCount[i];
            }
        }

        public int[] withdraw(int amount) {
            long[] temp = Arrays.copyOf(money, 5);
            long[] result = new long[]{0,0,0,0,0};
            int index = 4;
            while(index>=0 && amount != 0){
                if(amount>=face[index]) {
                    // 需要几张face面值
                    long a = amount / face[index];
                    // 有则取出
                    if(temp[index] >= a) {
                        temp[index] -= a;
                        // 余下
                        amount = amount - (int)(face[index] * a);
                        result[index] += a;
                    }else{
                        // 余下
                        result[index] += temp[index];
                        amount = amount - (int)(face[index] * temp[index]);
                        temp[index] = 0;
                    }
                }
                index--;
            }
            // 能够取出
            if(amount == 0){
                this.money = temp;
                return new int[]{(int)result[0],(int)result[1],(int)result[2],(int)result[3],(int)result[4]};
            }else{
                // 不能取出
                return new int[]{-1};
            }
        }
    }

/**
 * Your ATM object will be instantiated and called as such:
 * ATM obj = new ATM();
 * obj.deposit(banknotesCount);
 * int[] param_2 = obj.withdraw(amount);
 */
}
